#ifndef FILEADAPTER_H_
#define FILEADAPTER_H_

#include <string>
#include <dirent.h>
#include <regex>
#include "Thread.h"
#include "Observable.h"
#include "WorkQueue.h"

namespace inte {

class FileAdapter : public utils::Thread, public utils::Observable<std::string> {
public:
	FileAdapter(FileInputNode &fileInputNode) : _fileInputNode(fileInputNode), _status(Running) {}

	enum Status
	{
		Running,
		Stopped
	};

	Status getStatus() const {
		return _status;
	}

	void stop() {
		this->_status = Stopped;
	}

    void* run() {
        while (_status == Running) {

        	//get the file list base on the directory and file pattern
        	utils::WorkQueue<std::string> fileQueue;
        	listdir(_fileInputNode.getInputDirectory(), fileQueue, _fileInputNode.getPattern(),_fileInputNode.getExPattern());

        	while (fileQueue.size() != 0) {
        		std::cout << fileQueue.remove() << std::endl;
        	}

        	//start a new thread to load the message from a file into a some object.
        	std::string message;
        	message = "this is a test message";
        	this->setChanged();
        	//std::cout << "read files from " << _fileInputNode.getInputDirectory() << "\n";


        	//pass that object to a receiver and get a confirmation
        	if (this->notifyObservers(message)) {
        		std::cout << "file moved to archive " << "\n";
        	} else {
        		std::cout << "file transfer failed " << "\n";
        	}

        	//move or delete the file depends what is specified on the FileInputNote.

        	//wait for set number of seconds
        	sleep(_fileInputNode.getPollingInerval());
        }
        return NULL;
    }

private:
	FileInputNode &_fileInputNode;
	Status _status = Stopped;

	bool checkPattern(char fileName[], const std::string& regex_str) {
		if (regex_str == "") {
			return false;
		} else {
			std::regex reg(regex_str.c_str());
			if (regex_search(fileName, reg) ) {
				return true;
			} else {
				return false;
			}
		}


		return true;
	}

	int listdir(const std::string& path, utils::WorkQueue<std::string>& fileQueue, const std::string& regex_str, const std::string& regex_ex_str) {
		struct dirent *entry;
		DIR *dp;

		dp = opendir(path.c_str());
		if (dp == NULL) {
			return -1;
		}

		while ((entry = readdir(dp))) {
			if (strcmp (entry->d_name, ".") == 0 ||
		        strcmp (entry->d_name, "..") == 0 ||
		        checkPattern(entry->d_name, regex_ex_str)) {
				continue;
			}

			if (checkPattern(entry->d_name, regex_str)) {
				fileQueue.add(entry->d_name);
			}
		}

		closedir(dp);
		return 0;
	}

};

} /* namespace inte */

#endif /* FILEADAPTER_H_ */
